/**
 * Core functionality for creating and editting buttons.
 */

/** The button we're editing. */
var editButton = null;

/** Keep track of the cnt, so we can have unique ids. */
var buttonCount = 0;

/** Keep a cache of all the buttons. */
var allButtons2ones = [];

/** The prefix for params. */
var BUTTON_PREFIX = "_button_";

// XXX: onEnd isn't firing!!!!!!
// Note: this is taken straight from the source code, so instead of taking an element and event, 
//       this takes a name, draggable, and event
// @note:1: Because of this stupid bug, we need to map draggables to buttons, so that
//          when we end a drag we can recover the original button (arg!!!)
var draggables2buttons = $H({});
Draggables.addObserver({'onEnd': function(eventName,draggable,event) {
      var thiz = draggables2buttons.get(draggable);
      //thiz.setX(event.pointerX());
      //thiz.setY(event.pointerY());
      try {
        //edit(thiz);
      } catch (ignore) {}
    }});


var Button = Class.create();
Button.prototype = {

 initialize: function(el,imageEl,title,command,absolute) {
    this.el = el;
    this.imageEl = imageEl;
    if (imageEl) {
      this.image = imageEl.src;
    }
    this.title = title;
    this.command = command;
    this.image = null;
    if (absolute) {
      el.absolutize();
    }
    this.x = this._findX(el);
    this.y = this._findY(el);
    var thiz = this;
    var d = new Draggable($(el).id, { revert: false, snap: [5,5],
          onEnd: function() {
          alert(this);
        }});
    draggables2buttons.set(d,this); // See @note:1
    this.hide();
    allButtons2ones.push(this);
    this.newline = false;
  },

 // --- getters ---
 getElementId: function() {
    return this.el.id;
  },

 getX: function() {
    return this.x;
 },

 getY: function() {
    return this.y;
  },

 getElement: function() {
    return this.el;
  },

 getTitle: function() {
    return this.title;
  },
 
 getCommand: function() {
    return this.command;
  },

 getImage: function() {
   return this.image;
 },

 getNewline: function() {
    return this.newline;
  },
 
 // --- setters ---
 setTitle: function(title) {
    this.title = title;
  },
 
 setCommand: function(command) {
    this.command = command;
  },
 
 setBackgroundColor: function(color) {
    this.backgroundColor = color;
  },
 
 setForegroundColor: function(color) {
    this.foregroundColor = color;
  },
 
 setImage: function(image) {
    this.image = image;
    this.imageEl.src = image; // update the view
 },

 setCoords: function(x,y) {
    this.setX(x);
    this.setY(y);
  },
 
 setX: function(x) {
    var el = this.getElement();
    el.absolutize();
    el.style.left  = x + "px";
    this.x = x;
    return this;
  },

 setY: function(y) {
    var el = this.getElement();
    el.absolutize();
    el.style.top  = y + "px";
    this.y = y;
    return this;
  },

  setNewline: function(newline) {
   this.newline = newline;
   return this;
 },


 // --- misc ---

 destroy: function() {
    //allButtons2ones.set(this,false);
    //TODO
  },

 /**
  * Makes this visible.
  */
 show: function() {
    this.getElement().show();
    return this;
  },

 /**
  * Makes this hidden.
  */
 hide: function() {
    this.getElement().hide();
    return this;
  },

 /**
  * http://bytes.com/forum/thread90547.html
  */
 _findY: function( oElement ) {
    var o = oElement;
    var iReturnValue = 0;
    while( oElement != null ) {
      iReturnValue += oElement.offsetTop;
      oElement = oElement.offsetParent;
    }
    return iReturnValue - 65;
  },

 /** 
  * Derived from _findY. 
  */
 _findX: function( oElement ) {
    var iReturnValue = 0;
    while( oElement != null ) {
      iReturnValue += oElement.offsetLeft;
      oElement = oElement.offsetParent;
    }
    return iReturnValue;
  },

 reset: function() {
    this.reposition();
  },
 
 // end
 _null: function() {}
};

/**
 * Creates and returns a new button.
 *
 * @param image src of the image to use
 * @param name name of the button
 * @param absolute is this button positioned absoutely?
 * @return new button created from input
 */
function newButtonInstance(image,name,absolute) {

  // Create new element, taken from google.php
  var el = $n('span',$('buttons'));
  el.id = buttonId(name) + '_' + (buttonCount++);
  el.className = 'b';
  var a = $n('a',el);
  a.style.border = '0';
  a.href = '#';
  var img = $n('img',a);
  img.style.border = '0';

  img.src = image;

  // Default title and command
  var title = name;
  var command = name;
  
  // Create the new button!
  var b =  new Button(el,img,title,command,absolute);
  if ((document.location+"").match('/[\?\&]edit/')) {
    a.ondblclick = newEditFunction(b);
  }
  b.setImage(image);
  return b;
}

function newEditFunction(b) {
  var _b = b;
  return function(e) {
    try {
      edit(_b);
    } catch (ignore) { /* sloppy!!!!! /*/ }
  };
}

function buttonId(name) {
  return "button_" + name;
}

function editElementId(name) {
  return "edit_" + name + "_value";
}

function editElement(name) {
  return $(editElementId(name));
}

function setButtonField(field,value) {
    editElement(field).value = value;
}

function getButtonField(field) {
  return editElement(field).value;
}

function imagePreview() {
  return $('image_preview')
}

/**
 * Start editting a button.
 */
function edit(button) {

  // Save for later
  editButton = button;


  setButtonField('title'   , button.getTitle());
  setButtonField('command' , button.getCommand());
  setButtonField('x'       , button.getX());
  setButtonField('y'       , button.getY());
  setButtonField('image'   , button.getImage());
  imagePreview().src = button.getImage();
}

function save() {
  if (!editButton) {
    alert("Please select a button to edit first!");
    return;
  }
  var b = editButton;
  b.setTitle(getButtonField('title'));
  b.setCommand(getButtonField('command'));
  b.setX(getButtonField('x'));
  b.setY(getButtonField('y'));
  b.setImage(getButtonField('image'));

  b.reset();
}

function reset() {
  alert("No soup for you!");
}

function buttonToParams(b,index) {
  var val = "";
  val += "title=" + b.getTitle();
  val += "|command=" + b.getCommand();
  val += "|image=" + b.getImage();
  val += "|x=" + b.getX();
  val += "|y=" + b.getY();
  if (b.getNewline()) {
    val += "|newline=1";
  }
  var str = BUTTON_PREFIX + index + "=" + escape(val);
  return str;
}

function createLink() {

  // Create the base url
  var loc = document.location;
  var prot = loc.protocol;
  var path = loc.pathname;
  var host = loc.host;
  var page = path;
  

  var link = page + "?show";
  for (var i=0; i<allButtons2ones.length; i++) {
    link += "&" + buttonToParams(allButtons2ones[i],i);
  }
  document.location = link;
}

